#ifndef __ZEVENT_ZYS_STATUS_HPP
#define __ZEVENT_ZYS_STATUS_HPP
#include "kstring.hpp"
#include <type_traits>
namespace zevent {

#define ZEVENT_RESULT_ERR_DEFINE(name)                                         \
  constexpr auto name = zevent::KString { #name }

namespace result {
ZEVENT_RESULT_ERR_DEFINE(ok);
struct Null {};

template <typename T> constexpr auto is_null_v = std::is_same_v<T, Null>;

} // namespace result

template <typename TValue = result::Null, KString KErr = result::ok>
class Result {
public:
  constexpr Result(TValue) = default;
  using ValueType =
      std::conditional_t<KErr == result::ok, TValue, result::Null>;
  operator bool() const {
    if constexpr (KErr == result::ok) {
      return true;
    }
    return false;
  }
  auto Error() const { return std::string_view{KErr.value}; }
  template <typename TFn> auto Then(TFn &&fn) {
    if constexpr (KErr == result::ok) {
      return fn(std::move(value));
    }
    return *this;
  }
  template <typename TFn> auto Else(TFn &&fn) {
    if constexpr (KErr != result::ok) {
      return fn(Error());
    }
    return *this;
  }

private:
  ValueType value;
};

} // namespace zevent

#endif // !__ZEVENT_ZYS_STATUS_HPP
